#pragma once
#include "JsonRequest.hpp"
#include "sql_string.h"

template <class T>
class DataRequest : public JsonRequest< T >
{
public:
	DataRequest() :
		m_all(0),
		m_index(-1)
	{

	}

public:
	bool response()
	{
		std::string		page;
		std::string		size;
		std::string		all;
		sql_string<>	sql;
		sql_string<>	sql_count;
		sql_string<>	sql_data;

		if(false == request::get("page", page))
		{
			page = "0";
		}

		if(false == request::get("size", size))
		{
			size = "100";
		}

		if(false == ((T*)this)->get_count_sql(sql_count)
				|| false == ((T*)this)->get_data_sql(sql_data))
		{
			((T*)this)->err << "invalid paramter";
			return false;
		}

		m_page = atoi(page.c_str());
		m_size = atoi(size.c_str());
		if(m_size > 300)
		{
			m_size = 300;
		}
		else if(4 > m_size)
		{
			m_size = 4;
		}
		
		// 获取总数
		if(false == sql::signalQuery(sql_count.c_str(), &all, NULL))
		{
			((T*)this)->err << "invalid all count";
			return false;
		}

		m_all = atoi(all.c_str());
		// 当总长度为0时就不再执行查询
		if(0 == m_all)
		{
			((T*)this)->json.push_back(JSONNode("all", 0));
			((T*)this)->json.push_back(JSONNode("page_cur", 0));
			((T*)this)->json.push_back(JSONNode("page_all", 0));
			((T*)this)->json.push_back(JSONNode("page_size", m_size));
			return true;
		}

		int n = m_all / m_size;
		if(m_page > n)
		{
			m_page = n;
		}

		// 查询数据
		JSONNode		node(JSON_ARRAY);

		node.set_name("data");
		sql.format("%s", sql_data.c_str());
		sql.append(" limit %d,%d", m_page * m_size, m_size);
		if(false == sql::query(sql.c_str(), DataRequest<T>::callback, &node))
		{
			((T*)this)->err << "execute data sql failed:"
				<< sql.c_str();
			return false;
		}
		
		// 返回
		((T*)this)->json.push_back(JSONNode("all", m_all));
		((T*)this)->json.push_back(JSONNode("page_cur", m_page));
		((T*)this)->json.push_back(JSONNode("page_all", n));
		((T*)this)->json.push_back(JSONNode("page_size", m_size));
		((T*)this)->json.push_back(node);
		return true;
	}

public:
	static bool callback(void* context, int r, int c, MYSQL_ROW row)
	{
		JSONNode*		pnode	= (JSONNode *)context;
		JSONNode		node(JSON_ARRAY);

		for(int i = 0; i < c; i++)
		{
			if(NULL != row[i])
			{
				node.push_back(JSONNode("", (json_char *)(row[i])));
			}
			else
			{
				node.push_back(JSONNode("", ""));
			}
		}

		pnode->push_back(node);
		return true;
	}

private:
	unsigned int		m_page;
	unsigned int		m_size;
	unsigned int		m_all;
	int					m_index;
	
};

